﻿#include "FITKAbaqusAdaptorAssembly.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "FITKAbaqusAdaptorSurface.h"
#include "FITKAbaqusAdaptorSet.h"
#include "FITKAbaqusAdaptorConstraint.h"
#include "FITKAbaqusAdaptorTransform.h"
#include "FITKAbaqusAdaptorInertia.h"
#include "FITKAbaqusAdaptorSpringDashpot.h"
#include "FITKAbaqusAdaptorElement.h"
#include "FITKAbaqusAdaptorConnectorSection.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"
#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"
#include "FITK_Interface/FITKInterfaceModel/FITKAssInstance.h"
#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Interface/FITKInterfaceModel/FITKUnstructuredMesh.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaRefPoint.h" 
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMeshPartVTK.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Interface/FITKInterfaceModel/FITKMeshSurface.h"
#include "FITK_Interface/FITKInterfaceModel/FITKMeshSurfaceNode.h"
#include "FITK_Interface/FITKInterfaceModel/FITKMeshSurfaceElement.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintCoupling.h" 
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintTie.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintRigidBody.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaTransform.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInertiaPointMassInertia.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaEngineeringFeature.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInertiaManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSpringDashpotPoint2Point.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSpringDashpotManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorSection.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorAssignment.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorAssignmentManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorSectionManager.h"
#include <QDebug>
#include <cmath>
//命名空间
namespace IO
{
    QString FITKAbaqusAdaptorAssembly::getAdaptorClass()
    {
        //返回适配器类名
        return "IO::FITKAbaqusAdaptorAssembly";
    }
    void FITKAbaqusAdaptorAssembly::setCaseData(AbaqusData::FITKDataCase * caseData)
    {
        _caseData = caseData;
    }
    bool FITKAbaqusAdaptorAssembly::adaptR()
    {
        _assemblyData = dynamic_cast<Interface::FITKAbaAssembly*>(_dataObj);
        if (!_assemblyData || !_reader || !_caseData) return false;
        _reader->backLine();

        QString line = _reader->readLine();
        if (!line.toLower().startsWith("*assembly")) return false;
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString assemblyName = s["name"];
        _assemblyData->setDataObjectName(assemblyName);

        while (!_reader->atEnd())
        {
            bool readOK = false;
            line = _reader->readLine();
            if (!line.startsWith("*")) continue;
            s.reset(line);
            QString sH = s.getHeader().toLower();
            if (sH == "end assembly")
            {
                //inp文件中不存ref Points关键字，需要自动生成
                this->checkAssRefpoints(); //libaojun 
                return true;
            }
            else if (sH == "instance")
            {
                readOK = this->readInstance();
                if (!readOK) return false;
            }
            else if (_reader->getINPReadLevel() == INPReadLevel::ReadAssembly) continue;
            else if (sH == "node")
            {
                readOK = this->readNode();
                if (!readOK) return false;
            }
            else if (sH == "nset" || sH == "elset")
            {
                readOK = this->readSet();
                if (!readOK) return false;
            }
            else if (sH == "surface")
            {
                readOK = this->readSurface();
                if (!readOK) continue;
            }
            else if (sH == "coupling" || sH == "tie" || sH == "rigid body")
            {
                readOK = this->readConstraint();
                if (!readOK) continue;
            }
            else if (sH == "transform" || sH == "orientation")
            {
                readOK = this->readTransformOrientation();
                if (!readOK) continue;
            }
            else if (sH == "element")
            {
                readOK = this->readElement();
                if (!readOK)continue;
            }
            else if (sH == "mass" || sH == "rotary inertia")
            {
                readOK = this->readInertia();
                if (!readOK)continue;
            }
            else if (sH == "spring" || sH == "dashpot")
            {
                //设置不跳过空行
                _reader->setSkipBlankLine(false);
                readOK = this->readSpringDashpot();
                //设置跳过空行
                _reader->setSkipBlankLine(true);
                if (!readOK)continue;
            }
            else if (sH == "connector section")
            {
                readOK = this->readConnectorSection();
                if (!readOK)continue;
            }
            //读取成功后回退一行， 不用考虑注释行自动跳过
            if (readOK)
            {
                _reader->backLine();
                continue;
            }
        }
        return false;
    }
    bool FITKAbaqusAdaptorAssembly::adaptW()
    {
        _assemblyData = dynamic_cast<Interface::FITKAbaAssembly*>(_dataObj);
        if (!_assemblyData || !_writer || !_caseData) return false;

        bool isW = true;
        //获取数据流
        QTextStream* stream = _writer->getStream();
        QString name = _assemblyData->getDataObjectName();
        name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
        // 写出函数主体
        *stream << "*Assembly, name=" << name << endl;
        *stream << "**" << endl;
        isW &= writeInstance();
        isW &= writeNode();
        isW &= writeConnectorSection();
        isW &= writeSetSurf();
        //以下暂未完成
        //isW &= writeSurface();
        isW &= writeTransformOrientation();
        isW &= writeConstraint();
        isW &= writeInertia();
        isW &= writeSpringDashpot();
        //isW &= writeTie();
        *stream << "*End Assembly" << endl;
        return isW;
    }
    bool FITKAbaqusAdaptorAssembly::readInstance()
    {
        //回退一行 处理关键字信息
        _reader->backLine();
        //创建一个实例（Instance）对象
        Interface::FITKAssemblyInstance* instance = new Interface::FITKAssemblyInstance();
        if (!instance) return false;
        QString line = _reader->readLine();
        InpKeyLineSpliter s(line, _reader);
        QString instanceName = s["name"];
        instance->setDataObjectName(instanceName);
        QString partName = s["part"];
        auto part = _caseData->getPartManager()->getDataByName(partName);

        if (part == nullptr)
        {
            _reader->consoleMessage(3, "Get Part Error.");
            delete instance;
            return false;
        }
        instance->setModel(part);

        double tran3[3]{ 0., 0., 0. };
        double ax1[3]{ 0., 0., 0. };
        double ax2[3]{ 0., 0., 1. };
        double angle = 0.;
        while (!_reader->atEnd())
        {
            line = _reader->readLine();
            if (line.contains("*End Instance"))
            {
                //跳过结束标记 
                _reader->readLine();
                break;
            }
            QStringList sList = line.split(",");

            if (sList.size() == 3)
            {
                tran3[0] = sList[0].toDouble();
                tran3[1] = sList[1].toDouble();
                tran3[2] = sList[2].toDouble();
                // instance->transform(x, y, z);
            }
            else if (sList.size() == 7)
            {
                ax1[0] = sList[0].toDouble();
                ax1[1] = sList[1].toDouble();
                ax1[2] = sList[2].toDouble();

                ax2[0] = sList[3].toDouble();
                ax2[1] = sList[4].toDouble();
                ax2[2] = sList[5].toDouble();

                angle = sList[6].toDouble();

                //double ax[3];
                //double ay[3];
                //double angle;
                //ax[0] = sList[0].toDouble();
                //ax[1] = sList[1].toDouble();
                //ax[2] = sList[2].toDouble();
                //ay[0] = sList[3].toDouble();
                //ay[1] = sList[4].toDouble();
                //ay[2] = sList[5].toDouble();
                //angle = sList[6].toDouble();

                //instance->rotate(ax, ay, angle);
            }
        }

        instance->setTransform(tran3, ax1, ax2, angle);

        _assemblyData->appendDataObj(instance);
        return true;
    }
    bool FITKAbaqusAdaptorAssembly::readNode()
    {
        auto node = _assemblyData->getPoints();
        if (node == nullptr) return false;


        while (!_reader->atEnd())
        {
            QString line = _reader->readLine();
            if (line.startsWith("*"))return true;
            auto sList = line.split(",");

            Q_ASSERT(sList.size() == 4);
            if (sList.count() != 4) return false;

            // 点的编号
            int nodeID = sList[0].toInt();
            // 节点坐标
            double x = sList[1].toDouble();
            double y = sList[2].toDouble();
            double z = sList[3].toDouble();
            node->addNode(nodeID, x, y, z);
        }
        return false;
    }
    bool FITKAbaqusAdaptorAssembly::readSet()
    {
        Interface::FITKModelSet* set = new Interface::FITKModelSet();
        if (set == nullptr) return false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorSet>("INP", set);
        if (adaptor == nullptr)
        {
            delete set;
            return false;
        }

        //设置读取器
        adaptor->setFileReader(_reader);
        adaptor->setCaseData(_caseData);
        adaptor->setDataObject(set);
        bool ok = adaptor->adaptR();
        bool isTran = adaptor->isTransform();
        QString instanceName = adaptor->getInstanceName();

        if (adaptor != nullptr)
            delete adaptor;

        set->setModel(_assemblyData);
        if (!instanceName.isEmpty())
        {
            auto instance = _assemblyData->getDataByName(instanceName);
            if (instance == nullptr)
            {
                qDebug() << "Get instance Error.";
                return false;
            }
            set->setModel(instance);
        }

        if (ok)
        {
            auto setManager = _assemblyData->getComponentManager();
            if (isTran) delete set;
            else setManager->appendDataObj(set);
            return true;
        }
        //未正常结束
        delete set;
        return false;
    }
    bool FITKAbaqusAdaptorAssembly::readSurface()
    {
        //回退一行 处理关键字信息 确定单元类型
        _reader->backLine();
        QString line = _reader->readLine();
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString type = s["type"].toLower();
        //创建存储数据对象
        Interface::FITKMeshSurface* surface = nullptr;
        if (type == "element")
        {
            surface = new Interface::FITKMeshSurfaceElement;
        }
        else if (type == "node")
        {
            surface = new Interface::FITKMeshSurfaceNode;
        }
        if (!surface)return false;
        surface->setModel(_dataObj->getDataObjectID());
        //表面读取器
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorSurface>("INP", surface);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, QString("Create Assembly AdaptorSurface Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            delete surface;
            return false;
        }
        //设置文件读取器和存储的数据对象
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(surface);
        adaptor->setCaseData(_caseData);
        bool ok = adaptor->adaptR();
        //读取完毕释放截面属性读取器
        if (adaptor != nullptr)
            delete adaptor;
        if (ok)
        {
            //读取成功将数据对象放入管理
            _reader->consoleMessage(1, "Read Assembly Surface : " + surface->getDataObjectName());
            auto setsurfManager = _assemblyData->getComponentManager();
            setsurfManager->appendDataObj(surface);
            return true;
        }
        _reader->consoleMessage(3, QString("Read Assembly Surface Error : %1, File:%2, Line:%3").arg(surface->getDataObjectName()).arg(__FILE__).arg(__LINE__));
        delete surface;
        return false;
    }
    bool FITKAbaqusAdaptorAssembly::readConstraint()
    {
        //回退一行 处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString sH = s.getHeader().toLower();
        //创建存储数据对象
        Interface::FITKAbaAbstractConstraint* constraint = nullptr;
        if (sH == "coupling")
            constraint = new Interface::FITKAbaConstraintCoupling;
        else if (sH == "tie")
            constraint = new Interface::FITKAbaConstraintTie;
        else if (sH == "rigid body")
            constraint = new Interface::FITKAbaConstraintRigidBody;
        if (!constraint)return false;
        constraint->setParentDataID(_dataObj->getDataObjectID());
        //表面读取器
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorConstraint>("INP", constraint);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, QString("Create Assembly AdaptorConstraint Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            delete constraint;
            return false;
        }
        //设置文件读取器和存储的数据对象
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(constraint);
        adaptor->setCaseData(_caseData);
        bool ok = adaptor->adaptR();
        //读取完毕释放截面属性读取器
        if (adaptor != nullptr)
            delete adaptor;
        if (ok)
        {
            //读取成功将数据对象放入管理
            _reader->consoleMessage(1, "Read Assembly Constraint : " + constraint->getDataObjectName());
            auto constraintManager = _caseData->getConstraintManager();
            constraintManager->appendDataObj(constraint);
            return true;
        }

        //约束读取器
        _reader->consoleMessage(3, QString("Read Assembly Constraint Error : %1, File:%2, Line:%3").arg(constraint->getDataObjectName()).arg(__FILE__).arg(__LINE__));
        delete constraint;
        return false;
    }

    bool FITKAbaqusAdaptorAssembly::readTransformOrientation()
    {
        //回退一行 处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString sH = s.getHeader().toLower();
        //创建存储数据对象
        Interface::FITKCoordinateSystem* coordinate = nullptr;
        if (sH == "transform")
        {
            if (s["type"].toLower() == "c")
                coordinate = new Interface::FITKAbaTransform(Interface::FITKCoordinateSystem::FCSysType::FCSCylinder);
            else if (s["type"].toLower() == "s")
                coordinate = new Interface::FITKAbaTransform(Interface::FITKCoordinateSystem::FCSysType::FCSSphere);
            else if (s["type"].isEmpty() || s["type"].toLower() == "r")
                coordinate = new Interface::FITKAbaTransform(Interface::FITKCoordinateSystem::FCSysType::FCSCartesian);

            if (!coordinate)
                _reader->consoleMessage(3, QString("Read Transform's type Use of illegal parameters Error : type=%1, File:%2, Line:%3").arg(s["type"]).arg(__FILE__).arg(__LINE__));
        }
        else if (sH == "orientation")
        {
            if (s["system"].toUpper() == "CYLINDRICAL")
                coordinate = new Interface::FITKAbaTransform(Interface::FITKCoordinateSystem::FCSysType::FCSCylinder);
            else if (s["system"].toUpper() == "SPHERICAL")
                coordinate = new Interface::FITKAbaTransform(Interface::FITKCoordinateSystem::FCSysType::FCSSphere);
            else if (s["system"].isEmpty() || s["system"].toUpper() == "RECTANGULAR")
                coordinate = new Interface::FITKAbaTransform(Interface::FITKCoordinateSystem::FCSysType::FCSCartesian);

            if (!coordinate)
                _reader->consoleMessage(3, QString("Read Orientation's type Use of illegal parameters Error : type=%1, File:%2, Line:%3").arg(s["type"]).arg(__FILE__).arg(__LINE__));
        }
        if (!coordinate)return false;
        //读取器
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorTransform>("INP", coordinate);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, QString("Create Transform|Orientation AdaptorConstraint Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            delete coordinate;
            return false;
        }
        //设置文件读取器和存储的数据对象
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(coordinate);
        adaptor->setModelDataCaseData(_assemblyData, _caseData);
        bool ok = adaptor->adaptR();
        //读取完毕释放截面属性读取器
        if (adaptor != nullptr)
            delete adaptor;
        if (ok)
        {
            //读取成功将数据对象放入管理
            if (sH == "orientation")
                _reader->consoleMessage(1, "Read Orientation Constraint : " + coordinate->getDataObjectName());
            else if (sH == "transform")
                _reader->consoleMessage(1, "Read Transform Constraint : " + coordinate->getDataObjectName());
            auto transformManager = _assemblyData->getTransformManager();
            transformManager->appendDataObj(coordinate);
            return true;
        }

        //约束读取器
        _reader->consoleMessage(3, QString("Read Transform Error : %1, File:%2, Line:%3").arg(coordinate->getDataObjectName()).arg(__FILE__).arg(__LINE__));
        delete coordinate;
        return false;
    }

    bool FITKAbaqusAdaptorAssembly::readElement()
    {
        auto adaptor = new FITKAbaqusAdaptorElement;
        if (!adaptor)return false;
        //设置文件读取器和存储的数据对象
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(_assemblyData);
        bool ok = adaptor->adaptR();
        if (!ok)
            _reader->consoleMessage(3, QString("Read Assembly Element Error : File:%1, Line:%2").arg(__FILE__).arg(__LINE__));
        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorAssembly::readInertia()
    {
        //回退一行 处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString sH = s.getHeader().toLower();
        //创建存储数据对象
        Interface::FITKAbaAbstractInertia* inertia = nullptr;
        //点质量 与 转动惯量
        if (sH == "mass" || sH == "rotary inertia")
            inertia = new Interface::FITKAbaInertiaPointMassInertia;
        if (!inertia)return false;
        inertia->setModel(_dataObj->getDataObjectID());
        //惯性读取器
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorInertia>("INP", inertia);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, QString("Create Inertia AdaptorInertia Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            delete inertia;
            return false;
        }
        //设置文件读取器和存储的数据对象
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(inertia);
        adaptor->setAssemblyData(_assemblyData);
        bool ok = adaptor->adaptR();
        //读取完毕释放截面属性读取器
        if (adaptor != nullptr)
            delete adaptor;
        if (ok)
        {
            //读取成功将数据对象放入管理
            _reader->consoleMessage(1, "Read Inertia success : " + inertia->getDataObjectName());
            auto engineerFeature = _assemblyData->getAssemblyEngineerFeature();
            //惯性管理器
            Interface::FITKAbaInertiaManager* inertiaManager = engineerFeature->getInertiaManager();
            inertiaManager->appendDataObj(inertia);
            return true;
        }

        //约束读取器
        _reader->consoleMessage(3, QString("Read Inertia Error : %1, File:%2, Line:%3").arg(inertia->getDataObjectName()).arg(__FILE__).arg(__LINE__));
        delete inertia;
        return false;
    }

    bool FITKAbaqusAdaptorAssembly::readSpringDashpot()
    {
        if (!_reader)return false;
        //获取数据进行判断
        QString line1 = _reader->readLine().trimmed();
        QString line2 = _reader->readLine();
        _reader->backLine();
        _reader->backLine();
        int size = line2.split(',').size();
        //创建数据
        Interface::FITKAbaAbstractSpringDashpot* dataObj = nullptr;
        //两点弹簧
        if (line1.isEmpty() && size == 1)
            dataObj = new Interface::FITKAbaSpringDashpotPoint2Point;
        if (!dataObj)return false;
        //弹簧读取器
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorSpringDashpot>("INP", dataObj);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, QString("Create SpringDashpot AdaptorInertia Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            delete dataObj;
            return false;
        }
        //设置文件读取器和存储的数据对象
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(dataObj);
        adaptor->setModelDataCaseData(_assemblyData, _caseData);
        bool ok = adaptor->adaptR();
        //读取完毕释放截面属性读取器
        if (adaptor != nullptr)
            delete adaptor;
        if (ok)
        {
            //读取成功将数据对象放入管理
            _reader->consoleMessage(1, "Read SpringDashpot success : " + dataObj->getDataObjectName());
            auto engineerFeature = _assemblyData->getAssemblyEngineerFeature();
            //弹簧管理器
            Interface::FITKAbaSpringDashpotManager* manager = engineerFeature->getSpringDashManager();
            manager->appendDataObj(dataObj);
            return true;
        }

        //约束读取器
        _reader->consoleMessage(3, QString("Read SpringDashpot Error : %1, File:%2, Line:%3").arg(dataObj->getDataObjectName()).arg(__FILE__).arg(__LINE__));
        delete dataObj;
        return false;
    }

    bool FITKAbaqusAdaptorAssembly::readConnectorSection()
    {
        if (!_reader || !_caseData || !_assemblyData)return false;
        //获取连接器section管理器，连接器指派管理器
        Interface::FITKAbaConnectorSectionManager* sectionConnectManager = _caseData->getConnectorSectionManager();
        Interface::FITKAbaConnectorAssignmentManager* assignConnectManager = _assemblyData->getConnectorAssignManager();
        if (!sectionConnectManager || !assignConnectManager)return false;
        //创建连接器section数据
        Interface::FITKAbaConnectorSection* sectionData = new Interface::FITKAbaConnectorSection;
        if (!sectionData)return false;
        //创建连接器指派数据
        Interface::FITKAbaConnectorAssignment* assignData = new Interface::FITKAbaConnectorAssignment;
        if (!assignData)
        {
            delete sectionData;
            return false;
        }
        //获取当前连接器section的个数-为数据设置名称
        int count = sectionConnectManager->getDataCount();
        //连接器读取器
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorConnectorSection>("INP", sectionData);
        if (adaptor == nullptr)
        {
            _reader->consoleMessage(3, QString("Create ConnectorSection AdaptorInertia Error. File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            delete sectionData;
            return false;
        }
        //设置文件读取器和存储的数据对象
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(sectionData);
        adaptor->setConnectorAssignmentModelData(assignData, _assemblyData);
        bool ok = adaptor->adaptR();
        //读取完毕释放截面属性读取器
        if (adaptor != nullptr)
            delete adaptor;
        if (ok)
        {
            //读取成功将数据对象放入管理
            _reader->consoleMessage(1, "Read ConnectorSection success : " + sectionData->getDataObjectName());
            //设置名称
            QString name = sectionData->getDataObjectName();
            if (name.trimmed().isEmpty())
                sectionData->setDataObjectName(QString("ConnProp-%1").arg(count + 1));
            else
                sectionData->setDataObjectName(QString("ConnProp-%1_%2").arg(count + 1).arg(sectionData->getDataObjectName()));
            sectionConnectManager->appendDataObj(sectionData);
            assignConnectManager->appendDataObj(assignData);
            return true;
        }

        //约束读取器
        _reader->consoleMessage(3, QString("Read ConnectorSection Error : %1, File:%2, Line:%3").arg(sectionData->getDataObjectName()).arg(__FILE__).arg(__LINE__));
        delete sectionData;
        return false;
    }

    bool FITKAbaqusAdaptorAssembly::writeInstance()
    {
        // 获取数据流
        QTextStream* stream = _writer->getStream();
        int instanceNum = _assemblyData->getDataCount();
        if (instanceNum < 1) return true;

        for (int i = 0; i < instanceNum; ++i)
        {
            auto instance = _assemblyData->getDataByIndex(i);
            if (instance == nullptr) continue;
            auto model = instance->getModel();
            if (model == nullptr) continue;
            QString instanceName = instance->getDataObjectName();
            instanceName = instanceName.contains(' ') ? QString("\"%1\"").arg(instanceName) : instanceName;
            QString partName = model->getDataObjectName();
            partName = partName.contains(' ') ? QString("\"%1\"").arg(partName) : partName;
            *stream << QString("*Instance, name=%1, part=%2").arg(instanceName).arg(partName) << endl;
            auto tempInstance = dynamic_cast<Interface::FITKAssemblyInstance*>(instance);
            if (tempInstance != nullptr)
            {
                double  transform[3]{ 0,0,0 };
                double ax[3]{ 0,0,0 };
                double ay[3]{ 0,0,0 };
                double angle = 0;
                tempInstance->getTransfom(transform);
                tempInstance->getRotateAxis(ax, ay, &angle);
                // angle = tempInstance->getAngle();
                bool isT = false;
                bool isR = false;
                QStringList tempStrList;
                //平移是否有为0 ，为0则不写出
                isT |= JudgeZero(transform, sizeof(transform) / sizeof(double));
                //旋转是否为0，为0则不写
                isR |= JudgeZero(ax, sizeof(ax) / sizeof(double));
                isR |= JudgeZero(ay, sizeof(ay) / sizeof(double));
                isR |= angle > 0;
                if (isT || isR)
                {
                    *stream << _writer->double2String(transform[0], 15, 18) << ",";
                    *stream << _writer->double2String(transform[1], 15, 18) << ",";
                    *stream << _writer->double2String(transform[2], 15, 18) << endl;
                }
                if (isR)
                {
                    *stream << _writer->double2String(ax[0], 15, 18) << ",";
                    *stream << _writer->double2String(ax[1], 15, 18) << ",";
                    *stream << _writer->double2String(ax[2], 15, 18) << ",";
                    *stream << _writer->double2String(ay[0], 15, 18) << ",";
                    *stream << _writer->double2String(ay[1], 15, 18) << ",";
                    *stream << _writer->double2String(ay[2], 15, 18) << ",";
                    *stream << _writer->double2String(angle, 15, 18) << endl;
                }
            }
            *stream << "*End Instance" << endl;
            *stream << "**" << endl;
        }
        return true;
    }
    bool FITKAbaqusAdaptorAssembly::writeNode()
    {
        // 获取数据流
        QTextStream* stream = _writer->getStream();
        int nodeNum = _assemblyData->getPoints()->getNodeCount();
        for (int i = 0; i < nodeNum; ++i)
        {
            auto node = _assemblyData->getPoints()->getNodeAt(i);
            if (node == nullptr)
            {
                qDebug() << "assmbly node data error";
                return false;
            }
            *stream << "*Node" << endl;
            *stream << _writer->int2String(node->getNodeID(), 8) << ",";
            *stream << _writer->double2String(node->x(), 9, 18) << ",";
            *stream << _writer->double2String(node->y(), 9, 18) << ",";
            *stream << _writer->double2String(node->z(), 9, 18) << endl;
        }
        return true;
    }

    bool FITKAbaqusAdaptorAssembly::writeSetSurf()
    {
        auto setSurfManager = _assemblyData->getComponentManager();
        if (!setSurfManager)return false;
        int count = setSurfManager->getDataCount();
        bool ok = true;
        for (int i = 0; i < count; ++i)
        {
            auto data = setSurfManager->getDataByIndex(i);
            Interface::FITKModelSet* set = dynamic_cast<Interface::FITKModelSet*>(data);
            if (set)
                ok = writeSet(set);
            Interface::FITKMeshSurface* surface = dynamic_cast<Interface::FITKMeshSurface*>(data);
            if (surface)
                ok = writeSurface(surface);
        }
        return ok;
    }

    bool FITKAbaqusAdaptorAssembly::writeSet(Interface::FITKModelSet * set)
    {
        bool ok = false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorSet>("INP", set);
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(set);
        adaptor->setCaseData(_caseData);
        ok = adaptor->adaptW();
        delete adaptor;
        return ok;
    }

    bool FITKAbaqusAdaptorAssembly::writeSurface(Interface::FITKMeshSurface* surface)
    {
        auto setSurfManager = _assemblyData->getComponentManager();
        if (!setSurfManager)return false;
        bool ok = false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorSurface>("INP", surface);
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(surface);
        adaptor->setCaseData(_caseData);
        ok = adaptor->adaptW();
        delete adaptor;
        if (!ok)
            _writer->consoleMessage(3, QString("write Assembly Surface Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusAdaptorAssembly::writeConstraint()
    {
        auto constraintManager = _caseData->getConstraintManager();
        if (!constraintManager)return false;
        int count = constraintManager->getDataCount();
        bool ok = true;
        QTextStream* stream = _writer->getStream();
        for (int i = 0; i < count; ++i)
        {
            auto data = constraintManager->getDataByIndex(i);
            Interface::FITKAbaAbstractConstraint* constraint = dynamic_cast<Interface::FITKAbaAbstractConstraint*>(data);
            if (!constraint)continue;
            //通过工厂创建
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorConstraint>("INP", constraint);
            if (adaptor == nullptr) return false;
            *stream << QString("** Constraint: %1").arg(constraint->getDataObjectName()) << endl;
            adaptor->setFileWriter(_writer);
            adaptor->setCaseData(_caseData);
            adaptor->setDataObject(constraint);
            ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
                _writer->consoleMessage(3, QString("write Assembly Constraint Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            if (!ok) return false;
        }
        return true;
    }

    bool FITKAbaqusAdaptorAssembly::writeTransformOrientation()
    {
        if (!_caseData)return false;
        Interface::FITKAbaTransformManager* transformManager = _assemblyData->getTransformManager();
        int count = transformManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaTransform* transform = transformManager->getDataByIndex(i);
            if (!transform)continue;
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorTransform>("INP", transform);
            if (adaptor == nullptr) return false;
            adaptor->setFileWriter(_writer);
            adaptor->setDataObject(transform);
            adaptor->setModelDataCaseData(_assemblyData, _caseData);
            bool ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
                _writer->consoleMessage(3, QString("write Transform Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            if (!ok) return false;
        }
        return true;
    }

    bool FITKAbaqusAdaptorAssembly::writeInertia()
    {
        if (!_assemblyData)return false;
        //获取装配下的工程特性
        Interface::FITKAbaAssemblyEngineeringFeature* engineeringFeatureAssembly = _assemblyData->getAssemblyEngineerFeature();
        //获取惯量管理器
        Interface::FITKAbaInertiaManager* inertiaManager = engineeringFeatureAssembly->getInertiaManager();
        int count = inertiaManager->getDataCount();
        for (int i =  0; i < count; ++i)
        {
            Interface::FITKAbaAbstractInertia* inertia = inertiaManager->getDataByIndex(i);
            if (!inertia)continue;
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorInertia>("INP", inertia);
            if (adaptor == nullptr) return false;
            adaptor->setFileWriter(_writer);
            adaptor->setDataObject(inertia);
            adaptor->setWriteElementId(&_writeElementId);
            adaptor->setAssemblyData(_assemblyData);
            bool ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
                _writer->consoleMessage(3, QString("write Inertia Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            if (!ok) return false;
        }
        return true;
    }

    bool FITKAbaqusAdaptorAssembly::writeSpringDashpot()
    {
        if (!_assemblyData)return false;
        //获取装配下的工程特性
        Interface::FITKAbaAssemblyEngineeringFeature* engineeringFeatureAssembly = _assemblyData->getAssemblyEngineerFeature();
        //获取惯量管理器
        Interface::FITKAbaSpringDashpotManager* springDashManager = engineeringFeatureAssembly->getSpringDashManager();
        int count = springDashManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaAbstractSpringDashpot* springDashpot = springDashManager->getDataByIndex(i);
            if (!springDashpot)continue;
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorSpringDashpot>("INP", springDashpot);
            if (adaptor == nullptr) return false;
            adaptor->setFileWriter(_writer);
            adaptor->setDataObject(springDashpot);
            adaptor->setWriteElementId(&_writeElementId);
            adaptor->setModelDataCaseData(_assemblyData, _caseData);
            bool ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
                _writer->consoleMessage(3, QString("write SpringDashpot Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            if (!ok) return false;
        }
        return true;
    }

    bool FITKAbaqusAdaptorAssembly::writeConnectorSection()
    {
        if (!_assemblyData || !_writer)return false;
        //获取装配下的连接器指派的管理
        Interface::FITKAbaConnectorAssignmentManager* assignmentConnectManager = _assemblyData->getConnectorAssignManager();
        if (!assignmentConnectManager)return false;
        //写出连接器指派
        int count = assignmentConnectManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaConnectorAssignment* assignConnect = assignmentConnectManager->getDataByIndex(i);
            if (!assignConnect)continue;
            Interface::FITKAbaConnectorSection* sectionConnect = assignConnect->getTSectionObj<Interface::FITKAbaConnectorSection>();
            auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusAdaptorConnectorSection>("INP", sectionConnect);
            if (adaptor == nullptr) return false;
            adaptor->setFileWriter(_writer);
            adaptor->setDataObject(sectionConnect);
            adaptor->setConnectorAssignmentModelData(assignConnect, _assemblyData);
            adaptor->setWriteElementId(&_writeElementId);
            bool ok = adaptor->adaptW();
            delete adaptor;
            if (!ok)
                _writer->consoleMessage(3, QString("write SpringDashpot Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
            if (!ok) return false;
        }
        return true;
    }

    bool FITKAbaqusAdaptorAssembly::JudgeZero(double * d, int size)
    {
        for (int i = 0; i < size; ++i)
        {
            if (fabs(d[i]) > 0)
                return true;
        }
        return false;
    }

    void FITKAbaqusAdaptorAssembly::checkAssRefpoints()
    {
        //错误判断
        if (_assemblyData == nullptr) return;
        QList<int> existPoints; //已经生成参考点的id
        Interface::FITKAbaRefPointManager* refMgr = _assemblyData->getRefPoints();
        const int assID = _assemblyData->getDataObjectID();
        //遍历全部存在的参考点
        const int n = refMgr->getDataCount();
         for (int i = 0; i < n; ++i)
        {
            Interface::FITKAbaRefPoint* ref = refMgr->getDataByIndex(i);
            if(ref == nullptr) continue;
            ref->enable(true);
            if (ref->getAbsModelID() != assID) continue;
            const int nid = ref->getNodeID();
            //节点ID合法，记录id
            if (nid > 0) existPoints.append(nid);
        }
        Interface::FITKNodeList* nodelist = _assemblyData->getPoints();
        Interface::FITKComponentManager* compMgr = _assemblyData->getComponentManager();
        if (compMgr == nullptr) return;
        const int nNode = nodelist->getNodeCount();
        //遍历全部node
        for (int i = 0; i< nNode; ++i)
        {
            Core::FITKNode* node = nodelist->getNodeAt(i);
            //节点已经生成参考点
            if(node == nullptr || existPoints.contains(node->getNodeID()) ) continue;

            //是否已经存在单独的集合
            Interface::FITKModelSet* nodeset = compMgr->getSingleNodeSet(assID, node->getNodeID());
            if (nodeset == nullptr)
            {
                //创建集合
                nodeset = new Interface::FITKModelSet(Interface::FITKModelEnum::FITKModelSetType::FMSNode);
                nodeset->setModel(assID);
                nodeset->appendMember(node->getNodeID());
                nodeset->setInternal(true);
                nodeset->setDataObjectName(compMgr->checkName("_PickedSet-1"));
                compMgr->appendDataObj(nodeset);
            }

           
            //创建参考点
			Interface::FITKAbaRefPoint* refPt = _assemblyData->getRefPointBySet(nodeset->getDataObjectID(),assID);
			const QString cName = _assemblyData->getRefPoints()->checkName("RP-1");
			refPt->setDataObjectName(cName);
			refPt->enable(true);
        }

    }

}